function fn<T, K, U>(a: T, b: K, c: U) {}

fn<number, number, number>(1, 2, 3); // ok
fn(1, 2, 3); // ok

// 泛型参数有默认值
function fn1<T, K, U = any>(a: T, b: K, c: U) {}
fn1<number, number>(1, 2, 3);

// 泛型参数默认没有类型限制
function fn2<T>() {}
fn2<string>();
fn2<number>();
fn2<{}>();
fn2<[]>();

// 泛型参数的约束
interface Person {
  name: string;
}
function fn3<T extends Person>() {}
fn3<{ name: string; age: string }>();

// 泛型工具类型 Pick Omit Required Partial
interface People {
  name: string;
  age: number;
  sex?: string;
}

type P1 = Pick<People, "name" | "age">; // 从某个类型中挑选部分属性组成新类型
type P2 = Omit<People, "name" | "age">; // 从某个类型中排除部分属性，剩下属性组成新类型
type P3 = Required<People>; // 将类型中所有属性变成必选属性
type P4 = Partial<People>; // 将类型中所有属性变成可选属性

/*
  get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
    去掉泛型内容： 
      get(url: string, config?: AxiosRequestConfig): Promise
      get是一个函数，接受两个参数，一个url是必选，一个config可选，返回值是Promise

    泛型参数：<T = any, R = AxiosResponse<T>, D = any>
      三个泛型参数，都有默认值

    Promise<R> -> R 代表的是Promise结果值类型（const res = await promise; res的类型）

  delete<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
  post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
  put<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
*/

import axios from "axios";

(async () => {
  /*
    interface AxiosResponse<T = any, D = any> {
      data: T; // 响应体数据类型
      status: number;
      statusText: string;
      headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
      config: InternalAxiosRequestConfig<D>;
      request?: any;
    }

    假设data数据是：{ list: [], total: 0 }
  */
  // res 类型就是：AxiosResponse<any>
  interface IData {
    list: number[];
    total: number;
  }

  // const res = await axios.get<IData>("xxx");
  // console.log(res.data.list);
  // console.log(res.data.total);

  const request = axios.create({});
  request.interceptors.response.use(
    (response) => {
      return response.data;
    },
    () => {}
  );
  const res = await request.get<any, IData>("xxx");
})();

const li = document.querySelector("li") as HTMLLIElement;
